#include <ooGame/Game>
#include <ooGame/SoundActuator>
#include <ooGame/MouseSensor>

#include <osgDB/ReadFile>
#include <osgDB/WriteFile>

#include <osgODE/Notify>
#include <osgODE/Manager>
#include <osgODE/ManagerEventHandler>
#include <osgODE/World>
#include <osgODE/RigidBody>

#include <osgODEUtil/FindObjects>

#include <pSound/Source>





#ifndef OOGAME_DATA_PATH
#define OOGAME_DATA_PATH "../../data"
#endif




using namespace ooGame ;
using namespace osgODE ;
using namespace osgODEUtil ;
using namespace pSound ;




int
main(int argc, char** argv)
{
    osgDB::Registry::instance()->getDataFilePathList().push_back( OOGAME_DATA_PATH ) ;

    osg::ref_ptr<osg::Group>    root = NULL ;

    {
        osg::Node*  node = osgDB::readNodeFile("common_scene.osgb") ;
        PS_ASSERT1( node != NULL ) ;

        root = node->asGroup() ;
        PS_ASSERT1( root.valid() ) ;
    }


    osg::ref_ptr<Game>          game        = new Game() ;
    osg::ref_ptr<Sensor>        sensor1     = new MouseSensor( MouseSensor::MOUSE_OVER ) ;
    osg::ref_ptr<Sensor>        sensor2     = new MouseSensor( MouseSensor::LEFT_BUTTON ) ;
    osg::ref_ptr<Controller>    controller  = new Controller( Controller::AND ) ;
    osg::ref_ptr<SoundActuator> actuator    = new SoundActuator() ;



    game->setState( 1 ) ;

    game->getSensorList()       .push_back( sensor1 ) ;
    game->getSensorList()       .push_back( sensor2 ) ;
    game->getControllerList()   .push_back( controller ) ;
    game->getActuatorList()     .push_back( actuator ) ;

    sensor1->getControllerList()    .push_back( 0 ) ;
    sensor2->getControllerList()    .push_back( 0 ) ;
    controller->getActuatorList()   .push_back( 0 ) ;



    osg::ref_ptr<Manager>   manager = findManager( root ) ;
    PS_ASSERT1( manager.valid() ) ;

    osg::ref_ptr<World>     world = manager->getWorld() ;
    PS_ASSERT1( world.valid() ) ;



    manager->addEventCallback( new ManagerEventHandler() ) ;
    world->setEvents( new Events() ) ;


    world->setGravity( osg::Vec3() ) ;


    osg::ref_ptr<RigidBody> cube = NULL ;
    {
        cube = dynamic_cast<RigidBody*>( osgDB::readObjectFile("cube.osgb") ) ;
        PS_ASSERT1( cube.valid() ) ;

        cube->addUpdateCallback( game ) ;

        cube->setActorBound( osg::BoundingSphere( osg::Vec3(), 0.5 ) ) ;
    }


    osg::ref_ptr<Source>    source = NULL ;
    {
        Buffer*     buffer = dynamic_cast<Buffer*>( osgDB::readObjectFile("hit.wav") ) ;
        PS_ASSERT1( buffer ) ;

        source = new Source() ;
        source->setBuffer( buffer ) ;
    }
    actuator->setSource( source ) ;
    actuator->setMode( SoundActuator::PLAY_END ) ;


    root->addChild( source ) ;
    source->setAutoComputePosition( Source::COMPUTE_BY_VIEW ) ;


    world->addObject( cube ) ;


    osgDB::writeNodeFile( *root, "output.osgb" ) ;


    return 0 ;
}
